home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / Floating Windows / Floating Windows Code / Fixed Bug List⁄Notes < prev    next >
Encoding:
Text File  |  1995-07-18  |  17.8 KB  |  360 lines  |  [TEXT/R*ch]

  1. New Floater Notes 7/95:
  2.  
  3. There is no change to the API, so it should mostly just be a drop-in
  4. replacement, but there are two possible caveats:
  5.  
  6. 1) The WindowRecordExtensions structure doesn't exist any more, so if any of your
  7. code depends on it (it shouldn't) you'll have to change it.
  8.  
  9. 2) If your application uses the window refCon you'll have to change some code:
  10. Any windows created with NewReferencedWindow or GetNewReferencedWindow now use
  11. the window refCon to store a handle to the stuff that used to be in the old
  12. WindowRecordExtensions structure. However, a refCon is still provided for you:
  13. you simply need to replace any calls to the toolbox routines GetWRefCon and
  14. SetWRefCon in your code with calls to GetExtWRefCon and SetExtWRefCon, which are
  15. provided in WindowExtensions.c.
  16.  
  17. Below is a list of the bugs reported and comments about how they were resolved. Please
  18. send any further bugs to me at dkj@apple.com. No promises, but as long as time permits
  19. I'll try to maintain this code.
  20.  
  21. Dave Johnson
  22.  
  23. ======================================================================
  24. > GetNewReferencedWindow() uses the WDEF resource ID to determine whether or
  25. > not a window is a floater. It gets the WDEF resource ID by passing the
  26. > windowDefProc handle to GetResInfo(). Under 24-bit mode, the Window Manager
  27. > uses the high byte of the windowDefProc handle to store the WDEF variant
  28. > code. So if a non-zero variant is used in 24-bit mode, the Resource Manager
  29. > gets an invalid handle, returns -1 for the ID, and the window is treated as
  30. > a non-floating window. In addition to keeping the window from floating,
  31. > this can lead to crashes or other problems in applications that rely on the
  32. > windowKind field to distinguish between floaters and document windows.
  33. > I believe the fix is to call StripAddress on the windowDefProc handle in
  34. > the GetWindowDefProc() function as below...
  35. > Michael Wolfinbarger
  36. > Oklahoma Climatological Survey
  37. > wolfie@uoknor.edu
  38.  
  39. Fixed: GetNewReferencedWindow now uses a different method of determining whether
  40. the WIND specifies a floater: it looks inside the WIND itself for the WDEF ID.
  41.  
  42. ======================================================================
  43. > It seems that if there are open non-floating windows, and a new window A is
  44. > opened as invisible and with behind = -1, and a second window B is then opened
  45. > also as invisible with behind = -1, and then ShowReferencedWindow is called to
  46. > make window B visible, it never receives an activate event.
  47.  
  48. I couldn't reproduce this, but I didn't try until AFTER the big rewrite, so I
  49. assume it was fixed along the way.
  50.  
  51. ======================================================================
  52. > We noticed that the API does not allow one to specify the curvature of a rounded
  53. > window, e.g., rDocProc.  That is fine, but we noticed that the rounded windows
  54. > that were produced by NewReferencedWindow didn't look all that "rounded" as we
  55. > expected.  A little exploration into the code reveals why.  The constant
  56. > noGrowDocProc was being erroneously added to rDocProc to produce a variant of
  57. > rDocProc+4, whereas the "standard" curvature of a window is rDocProc+0 or
  58. > rDocProc+5.  The noGrowDocProc constant doesn't apply to the rounded window type,
  59. > and it seems unnatural to affect the curvature of the titlebar when the
  60. > kHasGrowBoxMask flag is changed.
  61. >  
  62. > The change to the code is simple; from
  63. > if (!(attributes & kHasGrowBoxMask))
  64. > to
  65. > if (titleBarType != kHasRoundedTitlebarMask && !(attributes & kHasGrowBoxMask))
  66. > does the trick, and makes the windows look nice and rounded like we'd expect.
  67.  
  68. Fixed. Also note that the process of turning window attributes (defined in
  69. WindowExtensions.h) into procIDs and state booleans was broken out into a new
  70. routine, AttributesToWindowInfo. This simplified NewWindowReference a lot.
  71.  
  72. ======================================================================
  73. > The routine HideReferencedWindow does not behave properly if you attempt to hide
  74. > more than one window at a time.  The result of hiding two windows is to leave the
  75. > windowing environment in a confused state: hiding the second window can make the
  76. > code think that the first hidden window is the frontmost nonfloater, even if
  77. > there are visible nonfloaters.  If you are interested, we will be happy to
  78. > forward a revised version of the routine to you, which corrects this problem. 
  79. > Our correction unfortunately requires more than just a line or two of code.
  80.  
  81. I couldn't reproduce this, but I didn't try until AFTER the big rewrite, so I
  82. assume it was fixed along the way.
  83.  
  84. ======================================================================
  85. > The routines SuspendFloatingWindows and ResumeFloatingWindows do not behave as we
  86. > would expect.  The sample application you provide simply calls
  87. > SuspendFloatingWindows when the application receives a suspend event.  But if
  88. > there are no floating windows open, first visible document window never receives
  89. > a deactivate event.  If there are floating windows open, the window does receive
  90. > a deactivate event.  The same is true for a resume event.
  91. > The obvious solution is for SuspendFloatingWindows never to deactivate the first
  92. > visible document window, or always to deactivate the first visible document
  93. > window, but not to deactivate it only sometimes.  We have changed the code so
  94. > that SuspendFloatingWindows always deactivates the first visible document window,
  95. > and so that ResumeFloatingWindows always activates the first visible document
  96. > window, since there is no sense in making the event handler do extra work.  The
  97. > necessary change is trivial.
  98.  
  99. Fixed. The first doc window is always activated or deactivated. If the first
  100. visible window is modal, nothing is done, preserving the state of the floaters
  101. and first doc window.
  102.  
  103. ======================================================================
  104.  
  105. > As long as I have you here, I might also make a suggestion.  I was surprised to
  106. > see the call to SelectWindow in the SelectReferencedWindow routine; this seems to
  107. > be the only place where the main event loop is relied upon to activate a window. 
  108. > Note that the result of this is that the application will behave differently
  109. > depending on whether or not floating windows are open: if floating windows are
  110. > open, the window will be activated immediately; if no floating windows are open,
  111. > the window will not be activated until we return to the main event loop.  In our
  112. > application, this was undesirable, so we changed the code to:
  113. > if (lastFloatingWindow == nil)
  114. > {
  115. >     DeactivateWindow(currentFrontWindow);
  116. >     BringToFront((WindowPtr) windowToSelect);
  117. >     HiliteWindow((WindowPtr)windowToSelect, kActivateWindow);
  118. >     ActivateWindow(windowToSelect);
  119. > } else {
  120.  
  121. Fixed.
  122.  
  123. ==============================================
  124. > When compiling with the -d STRICT_WINDOWS compiler flag, the WindowRecord
  125. > structure is no longer defined. As I understand things, this is to move toward a
  126. > fully preemptive Toolbox by making opaque toolbox interface objects.
  127. > As you know, when Copland arrives it may no longer be true that WindowRef ==
  128. > WindowPtr. In fact, a WindowRef, if used as a pointer, will probably point to
  129. > somewhere around Neptune.
  130. > If this is the case, then it is not a good thing to encapsulate a WindowRecord
  131. > inside your WindowRecordExtensions structure, and it is certainly bad to typecast
  132. > a WindowRef (like you might get back from the FrontWindow call) to a
  133. > WindowRecordExtensions record.
  134. > I had this same problem last year, when I first heard that our old friend the
  135. > WindowPtr was going away. So I decided to create my own window objects and store
  136. > them in a global table. That way I could still access my window data and keep my
  137. > code removed from any toolbox dependencies.
  138.  
  139. Fixed. After long and arduous debate, I decided to use the refCon of the window,
  140. rather than build and manage my own list. It was less work, and seemed like it
  141. would have the least impact on the existing API. I did, however, provide a
  142. replacement refCon that anyone can use. Users simply need to change all existing
  143. Get/SetWRefCon calls to Get/SetExtWRefCon: these are accessor routines that I
  144. wrote to use the new refCon. Pretty lightweight that way...
  145.  
  146. ======================================================================
  147. > I looked over the latest "develop 18" code that Troy sent me and noticed that the
  148. > new routine ValidateWindowList() doesn't make use of the WindowIsModal function. 
  149. > I suppose it would require an odd set of circumstances for ValidateWindowList to
  150. > be called while a modal window was in existence, but I bet it will happen to
  151. > someone sometime.
  152.  
  153. Fixed, ValidateWindowList just returns if the front window is modal.
  154. ======================================================================
  155. > Another thing that would be nice is if DeactivateFloatersAndFirstDocumentWindow()
  156. > and ActivateFloatersAndFirstDocumentWindow() behaved like ShowPen() and
  157. > HidePen(), and incremented a "activate level".  Although I've always thought it
  158. > was poor interface design to do so, some programs display dialogs on top of each
  159. > other.  If they have a standard routine that display dialogs then
  160. > ActivateFloatersAndFirstDocumentWindow() could end up getting called
  161. > inappropriately when the top dialog is dismissed.  A level count would prevent
  162. > this and simplify the model.
  163.  
  164. Fixed, I didn't use a level count, but
  165. ActivateFloatersAndFirstDocumentWindow checks for a modal dialog, and
  166. if one's up it does nothing.
  167. ======================================================================
  168. > It has severe problems with invisible windows.  If you have invisible windows
  169. > around, it is possible for the code to orphan a window from the process'
  170. > window list, with rather disasterous results.  
  171. > Basically, wherever the code uses the variable "windowBehind", it's broken. 
  172. > The reordering of the window list that goes on there can cause windows to be
  173. > orphaned.  I glanced at the new version from Dean that Troy Gaul sent me
  174. > today and it appears to still have this problem. 
  175. > Here are the relevant modifications I have made.  They seem to work, but have
  176. > not been heavily tested.  They are, however, definitely an improvement over
  177. > the original w.r.t. my usage of the floating windows code.
  178.  
  179. << code deleted >>
  180. Fixed, more or less, I think :-). ShowReferencedWindow and HideReferencedWindow
  181. were rewritten, pretty much from the ground up, and (I think) are much better. I
  182. expect some bugs will be found, though...
  183.  
  184. ======================================================================
  185.  
  186. > 1. We found it necessary to add code to NewWindowReference to support windows of
  187. > type movableDBoxProc.
  188. > 2. We added a constant kHasVerticalTitlebarMask and appropriate code to
  189. > NewWindowReference to support Infinity Windoid 3.0's vertical titlebar feature.
  190. > 3. We added code to NewWindowReference to support Infinity Windoid 3.0's zoom and
  191. > grow box features.
  192.  
  193. Fixed, all the variation codes and such match the 7.5 values (and Infinity 3.0),
  194. and movable modals are created correctly.
  195.  
  196. ================================================================================
  197.  
  198. > There is an implementation nasty bug in the Floater Sample.
  199. > You can reveal it by:
  200. >     - closing both floating windows,
  201. >     - opening the Find Dialog and moving it over the rectangle inside the 
  202. >         'Untitled' window (if not already here),
  203. >     - closing the Find Dialog.
  204. > Then the rectangle is redrawn empty as of an inactive window although the window is
  205. > active.
  206. > That is due to the doFill checking in DrawWindowContent():
  207. >     - 'true' is compiled by CW as 0x01,
  208. >     - while doFill is 0xFF when TRUE (hilite flag),
  209. > so doFill can be seen as FALSE!
  210. > IMHO, the '== true' comparison is generally a risky business. The lazy people, 
  211. > like me, who prefers to type only "if (doFill)" cannot run into this kind of
  212. > implementation problem.
  213.  
  214. Fixed! Thanks! That's a bizarre one. I actually think of this as a compiler bug myself,
  215. but that's probably unfair of me. :-)
  216.  
  217. ======================================================================
  218. After first test of rewrite:
  219. ======================================================================
  220. > 1. I am using SC 8.0.1 with Universal Interfaces 2.0 in “MPW Latest”
  221. > on ETO #17. I encountered three compiler errors:
  222. > i. Since GetWasVisible returns a Boolean, I needed to change return
  223. > nil to return FALSE.
  224. > ii. Since GetExtWRefCon returns a long, I needed to change return nil
  225. > to return 0.
  226. > iii. I needed to #include <Errors.h> to define resNotFound, used in
  227. > GetWINDStats.
  228.  
  229. Fixed.
  230. ======================================================================
  231. > 2. For consistency, I suggest that you make GetNextVisibleWindow an
  232. > "extern pascal" like all the other routines in the .h file.
  233.  
  234. Fixed
  235. ======================================================================
  236. > 3. I was somewhat surprised when I read "Who ever calls NewWindow to
  237. > make a dialog anyway?", since we rely on common a window creation
  238. > scheme for all our windowing needs.  The current implementation of
  239. > CheckWindowOrdering will place a modal window (including movable
  240. > modal dialogs) behind all floaters, which is not the desired result.
  241. > Are you recommending that we call NewDialog instead of NewWindow to
  242. > create our dialogs, and make sure we use Dialog Manager calls
  243. > everywhere so that we comply with STRICT_WINDOWS?  We were faithfully
  244. > following the advice in Technical #203, Managerial Abuse, and using
  245. > the window manager instead of the dialog manager for our complex
  246. > modal windows.  Is the best option for us to hack CheckWindowOrdering
  247. > to place modals in front of everything?  Since modal windows are not
  248. > supported correctly, shouldn't you remove them from
  249. > AttributesToWindowInfo?
  250.  
  251. Yikes. It was a little cavalier of me to eliminate the modal dialog
  252. case, and it's fixed now (both NewWindowReference and
  253. GetNewWindowReference check for modal windows, CheckWindowOdering
  254. only allows modals to be created in front of all windows, etc.)
  255. HOWEVER: my recommendation is definitely to make your code compile
  256. with STRICT_WINDOWS (srict EVERYTHING, actually). Someday, you'll
  257. have no choice, as a matter of fact, so the sooner the better. If
  258. that means you have to abuse the Dialog manager a bit, so be it (the
  259. dialog manager is a little more robust than when that tech note was
  260. written). If you can do it without dialog manager calls, that's even
  261. better.
  262. ======================================================================
  263. > 4. NewWindowReference currently ingores the refCon that is passed to
  264. > it as an argument.  This causes our application to crash, since our
  265. > activate routine, (which is called immediately by NewWindowReference)
  266. > needs the refCon.  Our activate routine calls GetExtWRefCon, which
  267. > returns a random result since the userRefCon field is never
  268. > initialized.
  269.  
  270. Whoops, sorry. Fixed. Also, GetNewWindowReference preserves whatever
  271. refcon was specified in the WIND resource.
  272.  
  273. ===========================================================================
  274. > two more suggestions on your new floating windows library.
  275. > 1. GetWindowPortRect() isn't used in your library. Also, it clashes
  276. > with ZoomCode.c
  277. > 2. Why are GetWasVisible()/SetWasVisible() public?
  278. > Can an application responsibly use this?
  279.  
  280. Fixed: Removed GetWindowPortRect. "Privatized" Get/SetWasVisible.
  281.  
  282. ===========================================================================
  283. > I had three problems:
  284. > 1. NewWindowReference ignores the refCon passed to it.
  285. > 2. SetWRefCon is used in Utilities.c  This was a mall change but this
  286. > is going to happen: legacy or snarfed code will need to be changed.
  287. > 3. I don't know if this is my fault, but you use Get1Resource to get
  288. > the appropriate WIND resource.  I changed this to GetResource. I
  289. > can't understand why it shouldn't be GetResource.
  290. > I did a little more checking with my application. 
  291. > Get1Resource('WIND', ..) was failing.  There are two resource files,
  292. > the application resource fork and the preferences file.  I use
  293. > StdPrefsLib.c to manage the preferences file.
  294.  
  295. 1. Fixed.
  296.  
  297. 2. Yep, it's bound to happen, unfortunately. Anyone using this code
  298. should do a very complete search for Get/SetWRefCon and change ALL
  299. occurrences.
  300.  
  301. 3. I'm going to leave it Get1Resource, since the app's resource file
  302. should be topmost in the resource chain when GetNewWindowReference is
  303. called. (That is, unless I hear from other folks about this too.)
  304. StdPrefsLib.c is probably at fault, not restoring the resource chain
  305. after its operations.
  306.  
  307. =========================================================================
  308. > A problem occurs whenever we create a modal window.  Our standard
  309. > method is to create a window as invisible, call NewControl, LNew,
  310. > etc., and then call ShowReferencedWindow.  The problem is that
  311. > ShowReferencedWindow doesn't make the window the FrontWindow if there
  312. > are floating windows open.  Thus, no matter what kind of filtering we
  313. > do in the event loop, the user can always click on the desktop to
  314. > switch out of the app, because the system does not see the FrontWindow
  315. > as modal.
  316. > A call to BringToFront if the window is modal (either in
  317. > ShowReferencedWindow or in our calling code) should do the trick.
  318.  
  319. Fixed. This necessitated another change, too: WindowIsModal used to
  320. return true only if the window's kind was dialogKind, but these
  321. manually created modal windows don't qualify. I tried just setting
  322. the window's kind to dialogKind myself, but that's disastrous (the
  323. system makes assumptions about such windows, and calls all kinds of
  324. dialog routines behind your back, resulting in nasty crashes). I
  325. tried changing WindowIsModal to return true if the window was
  326. dialogKind OR if its variant was a modal type (it used to be AND) but
  327. it turns out that some floater variants overlap with regular variants
  328. (for instance, a floater with a zoom box returns variant 5, the same
  329. as a movable modal). Now, WindowIsModal returns true if the window is
  330. NOT a floater, AND it is either dialogKind or a modal variant. Whew!
  331.